/*
	ZoneCalcultator contains the areas of one scene and it calculates the zone in which every object is located in each time instant.
*/

import java.io.FileReader;
import java.util.Vector;
import org.xml.sax.XMLReader;
import org.xml.sax.SAXException;
import com.sun.org.apache.xerces.internal.parsers.SAXParser;

class ZoneCalculator{

	
	protected String f_scene;//this file contains the scene information specified from the knowledge acquisition tool used to define zones, trajectories, etc.
	protected int i_camera; //number of the camera.
	protected Vector<Area> v_areas; //Vector of areas.
	

	public ZoneCalculator(String name_file, int camera){
		try{
			
			this.f_scene = name_file;
			this.i_camera = camera;
			this.v_areas = new Vector();

		}catch(Exception e){
	    	System.out.println(e);
		}
	}//end ZoneCalculator

/*
	loadKnowledge: this method parsers the XML that contains the Scene information. v_area vector is filled out.
*/
	public void loadKnowledge(){
		try{
			MyXMLHandlerScene handler = new MyXMLHandlerScene(this.v_areas);
			XMLReader parser = new SAXParser();
			parser.setContentHandler(handler); 
			parser.parse(this.f_scene);
			int pos = this.v_areas.size(); 
			
		}catch(Exception e){
			System.out.println("Error while processing xml file: "+e);		
		}
	}//end loadKnowledge

	public Vector<Membership> zoneClassification(int x, int y, int width, int height){
		//object's spatial data: x,y (central point of an object marked by an ellipse), width and height
		//Only object's support points are analysed. 
		//calculting the limits of the rect that involves the object (only support points).
		int x_min = x - (width/2);
		int x_max = x + (width/2);		
		int y_min = y;
		int y_max = y + (height/2);
		int total_points = width*(height/2);		
		
		int[] totalpoints_area = new int[this.v_areas.size()];	

		//inicialization

		for(int i=0;i<this.v_areas.size();i++)
			totalpoints_area[i]=0;	
		
		for(int i=x_min;i<x_max;i++){
			for(int j=y_min; j<y_max;j++){
				for(int w=0;w<this.v_areas.size();w++){
					Area a = this.v_areas.elementAt(w);
					if(pnpoly(a,i,j))
						totalpoints_area[w]++;			
				}
			}//end for
		}//end for
		
		//calculating membership values
		Vector v_membership_values = new Vector();
		for(int i=0;i<this.v_areas.size();i++){
			float mv = (float)totalpoints_area[i]/total_points;
			if(mv>0){
				
				Area a = this.v_areas.elementAt(i);
				Membership m = new Membership(a.getIdentificator(), mv);			
				v_membership_values.add(m);
			}
		}
		return v_membership_values;
	}

/*Checks if one point belongs to the area of a polygon */
	private boolean pnpoly(Area a, int testx, int testy){
		int i, j; 
		int nvert = a.getNumberOfPoints();
		boolean c = false;
	
	
      	for (i = 0, j = nvert-1; i < nvert; j = i++) {
			Point point_i = a.getPointAtPosition(i);
			Point point_j = a.getPointAtPosition(j);			
 
       		if (((point_i.getY()>testy) != (point_j.getY()>testy)) &&  (testx < (point_j.getX()-point_i.getX()) * (testy-point_i.getY())/ (point_j.getY()-point_i.getY()) + point_i.getX())){
	        	c = !c;
				
			}//end if     	
		}//end for

     return c;

   }//enf pnpoly

	public void printAreas(){
		for(int i=0;i<this.v_areas.size();i++){
			Area a = this.v_areas.elementAt(i);
			System.out.println("\nArea:"+a.getIdentificator());
			int points = a.getNumberOfPoints();
			for(int j=0;j<points;j++){
				Point p = a.getPointAtPosition(j);
				System.out.print("("+p.getX()+","+p.getY()+")");		
			}		
		}
	}

	
}//end class
